﻿namespace EyeOpen.Dependency
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    public class DependencyContainerService
    {
        private const string DependencyContainerKey = "DependencyContainer";

        private const string ContainerConfiguratorListKey = "ContainerConfiguratorList";

        private static HashSet<IContainerConfigurator> containerConfiguratorList;

        private static IDependencyContainer instance;

        public static IDependencyContainer Instance
        {
            get
            {
                if (HttpContext.Current == null)
                {
                    if (instance == null)
                    {
                        instance = CreateDependencyInstance();
                    }

                    return instance;
                }

                if (HttpContext.Current.Cache[DependencyContainerKey] == null)
                {
                    HttpContext.Current.Cache.Insert(DependencyContainerKey, CreateDependencyInstance());
                }
 
                return (IDependencyContainer) HttpContext.Current.Cache[DependencyContainerKey];
            }
        }

        private static HashSet<IContainerConfigurator> ContainerConfiguratorList
        {
            get
            {
                if (HttpContext.Current == null)
                {
                    if (containerConfiguratorList == null)
                    {
                        containerConfiguratorList = new HashSet<IContainerConfigurator>();
                    }

                    return containerConfiguratorList;
                }

                if (HttpContext.Current.Cache[ContainerConfiguratorListKey] == null)
                {
                    HttpContext.Current.Cache.Insert(ContainerConfiguratorListKey, new HashSet<IContainerConfigurator>());
                }

                return (HashSet<IContainerConfigurator>)HttpContext.Current.Cache[ContainerConfiguratorListKey];
            }
        }

        public static void Configure<TConfigurator>() where TConfigurator : class, IContainerConfigurator, new()
        {
            var configurator =
                ContainerConfiguratorList
                    .Where(c => c.GetType() == typeof(TConfigurator))
                    .SingleOrDefault();

            if (configurator == null)
            {
                configurator = new TConfigurator();
                configurator.Configure(Instance);
                ContainerConfiguratorList.Add(configurator);
            }
        }

        private static IDependencyContainer CreateDependencyInstance()
        {
            return 
                new DependencyContainerFactory()
                    .CreateDependencyContainer();
        }
    }
}